/**
 * OSAmI: Open Source Ambient Intelligence
 * A simple discovery protocol (based on multicast communications) for constrained devices.
 * Copyright (C) Lionel Debroux 2006 (as a TER/Magistere M1 student in the LSR-IMAG-ADELE team, for a demo in the H-Omega project)
 * Copyright (C) Lionel Debroux 2010 (as an engineer in the LCIS-INPG-CTSYS team, for a pre-demo in the FR part of the OSAMI project)
 * Contact: osami-general@osami-commons.org
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation;
 * version 2.1 of the License.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Suite 500 Boston, MA 02110-1335 USA
 */

package fr.imag.adele.homega.impl.discovery;

import java.util.logging.Logger;
import java.util.Dictionary;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Set;
import java.util.Map.Entry;

import fr.imag.adele.homega.impl.discovery.Device;

/**
 * This class encapsulates the external representation of events, and defines several constant strings used by the other classes
 * of the same package. Having those defined in a single place makes it easier to change the format. 
 */
public class DeviceEvent {

	/**
	 * Separator between key and value in a key-value pair.
	 */
	public static final String DEVICE_EVENT_KV_SEPARATOR = "|";

	/**
	 * Separator between key-value pairs.
	 */
	public static final String DEVICE_EVENT_FIELD_SEPARATOR = ";";


	private HashMap<String,String> info;
	private String id;


	public DeviceEvent(String id) {
		info = new HashMap<String,String>();
		this.id = id;
	}
	
	/**
	 * Add
	 * @param property
	 * @param value
	 * @throws Exception
	 */
	public void addInfo(String property, String value) throws Exception {
		//Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).info("Adding information \"" + property + "|" + value + "\"");
		if (   property.indexOf(DEVICE_EVENT_KV_SEPARATOR) != -1
			|| property.indexOf(0) != -1
			|| value.indexOf(DEVICE_EVENT_KV_SEPARATOR) != -1
			|| value.indexOf(0) != -1) {
			throw new Exception("Info contains \"" + DEVICE_EVENT_KV_SEPARATOR + "\" or null characters, skipping !");
		}
		else {
			info.put(property, value);
		}
	}

	public void removeInfo(String property) {
		//Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).info("Removing information for \"" + property + "\"");
		info.remove(property);
	}

	public String getInfo(String property) {
		String value = null;
		//Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).info("Getting information for \"" + property + "\"");
		value = info.get(property);

		return value;
	}

	static Dictionary<String,String> parseEvent(String _string) {
		String [] strings;
		String [] strings2;
		Dictionary<String,String> dict = null;

		strings = _string.split(DeviceEvent.DEVICE_EVENT_FIELD_SEPARATOR);
		if ((strings.length == 0) ||
			((strings.length == 1) && (strings[0].equals("")))) {
			Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).warning("Empty properties, cannot generate an event for the EventAdmin !");
		}
		else {
			dict = new Hashtable<String,String>();
			for (int i = 0; i < strings.length; i++) {
				strings2 = strings[i].split("\\" + DeviceEvent.DEVICE_EVENT_KV_SEPARATOR);
				
				if ((strings2.length != 2) || (strings[i].equals(""))) {
					Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).warning("Malformed EVENT \"" + strings[i] + "\"");
				}
				else {
					dict.put(strings2[0], strings2[1]);
				}
			}
		}
		return dict;
	}


	public String toString() {
		String str = new String(id + Device.DEVICE_FIELD_SEPARATOR);
		Set<Entry<String,String>> set = info.entrySet();
		Iterator<Entry<String,String>> i = set.iterator();
		Entry<String,String> e;

		while (i.hasNext()) {
			e = i.next();
			str = str + e.getKey() + DEVICE_EVENT_KV_SEPARATOR + e.getValue() + DEVICE_EVENT_FIELD_SEPARATOR;
		}

		return str + Device.DEVICE_FIELD_SEPARATOR;
	}

	/*public byte [] toBytes() {
		return this.toString().getBytes();
	}*/
}
